package com.fg.pro.trade.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fg.pro.model.trade.dto.GmCategoryDto;
import com.fg.pro.model.trade.dto.GmGoodsDto;
import com.fg.pro.trade.dao.TradeGoodsDao;
import com.fg.pro.trade.entity.TradeCategory;
import com.fg.pro.trade.entity.TradeGoods;
import com.fg.pro.trade.entity.TradeGoodsUnit;
import com.fg.pro.trade.service.TradeGoodsService;
import com.fg.pro.trade.service.TradeGoodsUnitService;
import com.fg.pro.trade.utils.GmHttpUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import jakarta.annotation.Resource;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.fg.pro.trade.utils.GmRequestUrl.GM_GOODS_URL;
import static com.fg.pro.trade.utils.GmRequestUrl.REDIS_LOCK_URL;

/**
 * 商品(TradeGoods)表服务实现类
 *
 * @author makejava
 * @since 2025-08-12 09:18:13
 */
@Service("tradeGoodsService")
public class TradeGoodsServiceImpl extends ServiceImpl<TradeGoodsDao, TradeGoods> implements TradeGoodsService {

    @Autowired
    GmHttpUtils gmHttpUtils;
    @Resource
    private TradeGoodsUnitService tradeGoodsUnitService;
    @Autowired
    RedissonClient redissonClient;
    @Override
    public PageInfo getPage(Integer pageNum, Integer pageSize, String goodsName) {
        PageHelper.startPage(pageNum, pageSize);
        List<TradeGoods> list = query().eq(StrUtil.isNotBlank(goodsName),"goods_name",goodsName).list();
        PageInfo<TradeGoods> pageInfo = new PageInfo<>(list);
        return pageInfo;
    }

    @Override
    public boolean refresh(Date date) throws InterruptedException {
        RLock lock = redissonClient.getLock(REDIS_LOCK_URL+GM_GOODS_URL);
        boolean tryLock = lock.tryLock();
        if(!tryLock){
            return false;
        }
        try {
            // 采取异步，更新执行时间过长
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        refreshTradeGoodsByLock(date);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            },"refreshTradeGoodsByLock-Thread").start();
            return false;
        } catch (RuntimeException e) {
            throw new RuntimeException(e);
        } finally {
            lock.unlock();
        }
    }

    @Transactional
    public boolean refreshTradeGoodsByLock(Date date) throws InterruptedException {
        LinkedList<TradeGoods> list = new LinkedList<>();
        LinkedList<TradeGoodsUnit> unitList = new LinkedList<>();
        // 获取请求参数 条件变量
        int num = 0;
        int limit = 999;
        while (true){
            System.out.println("num-->"+num);
            System.out.println("offset-->"+num*limit);
            GmGoodsDto.GmGoodsReponse gmGoodsReponse = gmHttpUtils.httpPostByToken(GM_GOODS_URL, new GmGoodsDto().new GmGoodsRequest().gmGoodsRequest(limit, num * limit), GmGoodsDto.GmGoodsReponse.class);
            for (GmGoodsDto.GmGoodsReponse.GmGoodsData gmGoodsData : gmGoodsReponse.getSkus()) {
                TradeGoods tradeGoods = new TradeGoods();
                tradeGoods.setId(gmGoodsData.getSku_id());
                tradeGoods.setGoodsRevision(gmGoodsData.getRevision());
                tradeGoods.setCreateTime(new Date(gmGoodsData.getCreate_time()));
                tradeGoods.setUpdateTime(new Date(gmGoodsData.getUpdate_time()));
                tradeGoods.setGoodsGroupId(gmGoodsData.getGroup_id());
                tradeGoods.setGoodsStationId(gmGoodsData.getStation_id());
                tradeGoods.setCategoryId(gmGoodsData.getCreator_id());
                tradeGoods.setGoodsCategoryFirId(gmGoodsData.getCategory1_id());
                tradeGoods.setGoodsCategorySecId(gmGoodsData.getCategory2_id());
                tradeGoods.setGoodsCategoryTirId(gmGoodsData.getCategory3_id());
                tradeGoods.setGoodsSkuId(gmGoodsData.getSku_id());
                tradeGoods.setGoodsSpuId(gmGoodsData.getSpu_id());
                tradeGoods.setGoodsBaseUnitId(gmGoodsData.getBase_unit_id());
                tradeGoods.setGoodsBaseUnitName(gmGoodsData.getBase_unit_name());
                tradeGoods.setGoodsMaxUnitId(gmGoodsData.getMax_unit_id());
                tradeGoods.setGoodsName(gmGoodsData.getName());
                tradeGoods.setGoodsPinyinLetter(gmGoodsData.getName_pinyin_letter());
                tradeGoods.setGoodsPinyinFirstLetter(gmGoodsData.getName_pinyin_first_letter());
                tradeGoods.setGoodsCustomizeCode(gmGoodsData.getCustomize_code());
                tradeGoods.setGoodsSkuType(gmGoodsData.getSku_type());
                tradeGoods.setGoodsDispatchType(gmGoodsData.getDispatch_type());
                tradeGoods.setSupplierId(gmGoodsData.getSupplier_id());
                tradeGoods.setGoodsProductionUnitId(gmGoodsData.getProduction_unit_id());
                tradeGoods.setGoodsProductionUnitName(gmGoodsData.getProduction_unit().getName());
                tradeGoods.setGoodsProductionUnitRate(gmGoodsData.getProduction_unit().getRate());
                tradeGoods.setGoodsProductionUnitParentId(gmGoodsData.getProduction_unit().getParent_id());
                tradeGoods.setGoodsPurchaseUnitId(gmGoodsData.getPurchase_unit_id());
                if(gmGoodsData.getOn_sale()!=null){
                    tradeGoods.setGoodsOnSale(gmGoodsData.getOn_sale()?1:0);
                }
                if(gmGoodsData.getIs_weight()!=null){
                    tradeGoods.setGoodsIsWeight(gmGoodsData.getIs_weight()?1:0);
                }
                tradeGoods.setGoodsPackageCalculateType(gmGoodsData.getPackage_calculate_type());
                tradeGoods.setGoodsPackageNum(gmGoodsData.getPackage_num());
                tradeGoods.setGoodsBarCode(gmGoodsData.getBar_code());
                tradeGoods.setGoodsMinPrice(gmGoodsData.getMin_price());
                tradeGoods.setGoodsMaxPrice(gmGoodsData.getMax_price());
                tradeGoods.setGoodsSupplierCooperateModelType(gmGoodsData.getSupplier_cooperate_model_type());
                tradeGoods.setGoodsHavePurchaseRule(gmGoodsData.getHave_purchase_rule()==2?0:1);
                tradeGoods.setGoodsWarehouseId(gmGoodsData.getWarehouse_id());
                tradeGoods.setGoodsCreatorId(gmGoodsData.getCreator_id());
                tradeGoods.setGoodsCreatorName(gmGoodsData.getCreator_name());
                tradeGoods.setGoodsPurchaseSkuType(gmGoodsData.getPurchase_sku_type());
                tradeGoods.setGoodsSortNum(gmGoodsData.getSort_num());
                tradeGoods.setGoodsSource(gmGoodsData.getSource());
                tradeGoods.setSupplyStationId(gmGoodsData.getSupply_station_id());
                tradeGoods.setGoodsSkuBatchType(gmGoodsData.getSku_batch_type());
                tradeGoods.setGoodsSkuBatchTypeEffectuateTime(new Date(gmGoodsData.getSku_batch_type_effectuate_time()));
                list.add(tradeGoods);

                if((gmGoodsData.getUnits().getUnits())!=null){
                    for (GmGoodsDto.GmGoodsReponse.GmGoodsData.Units.UnitData unit : gmGoodsData.getUnits().getUnits()) {
                        TradeGoodsUnit tradeUnit = new TradeGoodsUnit();
                        tradeUnit.setId(unit.getUnit_id());
                        tradeUnit.setGoodsUnitName(unit.getName());
                        tradeUnit.setGoodsUnitRate(unit.getRate());
                        tradeUnit.setGoodsUnitParentId(unit.getParent_id());
                        unitList.add(tradeUnit);
                    }
                }
            }

            if(gmGoodsReponse.getPaging().has_more==null){
                break;
            }
            num +=1;
            TimeUnit.SECONDS.sleep(1);
        }
        tradeGoodsUnitService.saveOrUpdateBatch(unitList);
        boolean save = saveOrUpdateBatch(list);
        return save;
    }

    @Override
    public Map<String, Long> getIdAndCode() {
        List<TradeGoods> list = query().list();
        Map<String, Long> map = list.stream().collect(Collectors.toMap(TradeGoods::getGoodsCustomizeCode, TradeGoods::getId));
        return map;
    }
}

